home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 003 / motorola / Sources / c / do11 < prev    next >
Text File  |  1993-07-17  |  9KB  |  295 lines

  1. #define HC11
  2.  
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6.  
  7. #include "proto.h"
  8. #include "as.h"
  9. #include "extvars.h"
  10. #include "structs.h"
  11.  
  12.  
  13. /*
  14.  * MC68HC11 specific processing
  15.  */
  16.  
  17. #define PAGE1   0x00
  18. #define PAGE2   0x18
  19. #define PAGE3   0x1A
  20. #define PAGE4   0xCD
  21.  
  22. /* addressing modes */
  23. #define IMMED   0
  24. #define INDX    1
  25. #define INDY    2
  26. #define LIMMED  3               /* long immediate */
  27. #define OTHER   4
  28.  
  29. int             yflag = 0;      /* YNOIMM, YLIMM, and CPD flag */
  30.  
  31. /*
  32.  * localinit --- machine specific initialization
  33.  */
  34. void
  35. localinit(void)
  36. {
  37. }
  38.  
  39. /*
  40.  * do_op --- process mnemonic
  41.  * 
  42.  * Called with the base opcode and it's class. Optr points to the beginning of
  43.  * the operand field.
  44.  */
  45. void
  46. do_op(int opcode, int class)
  47. /* int opcode; base opcode */
  48. /* int class;  mnemonic class */
  49. {
  50.         int             dist;   /* relative branch distance */
  51.         int             amode;  /* indicated addressing mode */
  52.         char           *peek;
  53.  
  54.  
  55.         /* guess at addressing mode */
  56.         peek = Optr;
  57.         amode = OTHER;
  58.         while (!delim(*peek) && *peek != EOS)   /* check for comma in operand
  59.                                                  * field */
  60.                 if (*peek++ == ',') {
  61.                         if (mapdn(*peek) == 'y')
  62.                                 amode = INDY;
  63.                         else
  64.                                 amode = INDX;
  65.                         break;
  66.                 }
  67.         if (*Optr == '#')
  68.                 amode = IMMED;
  69.  
  70.         yflag = 0;
  71.         switch (class) {
  72.         case P2INH:
  73.                 emit(PAGE2);
  74.         case INH:               /* inherent addressing */
  75.                 emit(opcode);
  76.                 return;
  77.         case REL:               /* relative branches */
  78.                 eval();
  79.                 dist = Result - (Pc + 2);
  80.                 emit(opcode);
  81.                 if ((dist > 127 || dist < -128) && Pass == 2) {
  82.                         error("Branch out of Range");
  83.                         emit(lobyte(-2));
  84.                         return;
  85.                 }
  86.                 emit(lobyte(dist));
  87.                 return;
  88.         case LONGIMM:
  89.                 if (amode == IMMED)
  90.                         amode = LIMMED;
  91.         case NOIMM:
  92.                 if (amode == IMMED) {
  93.                         error("Immediate Addressing Illegal");
  94.                         return;
  95.                 }
  96.         case GEN:               /* general addressing */
  97.                 do_gen(opcode, amode, PAGE1, PAGE1, PAGE2);
  98.                 return;
  99.         case GRP2:
  100.                 if (amode == INDY) {
  101.                         Cycles++;
  102.                         emit(PAGE2);
  103.                         amode = INDX;
  104.                 }
  105.                 if (amode == INDX)
  106.                         do_indexed(opcode);
  107.                 else {          /* extended addressing */
  108.                         eval();
  109.                         emit(opcode + 0x10);
  110.                         eword(Result);
  111.                 }
  112.                 return;
  113.         case CPD:               /* cmpd */
  114.                 if (amode == IMMED)
  115.                         amode = LIMMED;
  116.                 if (amode == INDY)
  117.                         yflag = 1;
  118.                 do_gen(opcode, amode, PAGE3, PAGE3, PAGE4);
  119.                 return;
  120.         case XNOIMM:            /* stx */
  121.                 if (amode == IMMED) {
  122.                         error("Immediate Addressing Illegal");
  123.                         return;
  124.                 }
  125.         case XLIMM:             /* cpx, ldx */
  126.                 if (amode == IMMED)
  127.                         amode = LIMMED;
  128.                 do_gen(opcode, amode, PAGE1, PAGE1, PAGE4);
  129.                 return;
  130.         case YNOIMM:            /* sty */
  131.                 if (amode == IMMED) {
  132.                         error("Immediate Addressing Illegal");
  133.                         return;
  134.                 }
  135.         case YLIMM:             /* cpy, ldy */
  136.                 if (amode == INDY)
  137.                         yflag = 1;
  138.                 if (amode == IMMED)
  139.                         amode = LIMMED;
  140.                 do_gen(opcode, amode, PAGE2, PAGE3, PAGE2);
  141.                 return;
  142.         case BTB:               /* bset, bclr */
  143.         case SETCLR:            /* brset, brclr */
  144.                 opcode = bitop(opcode, amode, class);
  145.  
  146.                 if (amode == INDX)
  147.                         Cycles++;
  148.                 if (amode == INDY) {
  149.                         Cycles += 2;
  150.                         emit(PAGE2);
  151.                         amode = INDX;
  152.                 }
  153.                 emit(opcode);
  154.                 eval();
  155.                 emit(lobyte(Result));   /* address */
  156.                 if (amode == INDX)
  157.                         Optr += 2;      /* skip ,x or ,y */
  158.                 Optr = skip_white(Optr);
  159.                 eval();
  160.                 emit(lobyte(Result));   /* mask */
  161.                 if (class == SETCLR)
  162.                         return;
  163.                 Optr = skip_white(Optr);
  164.                 eval();
  165.                 dist = Result - (Pc + 1);
  166.                 if ((dist > 127 || dist < -128) && Pass == 2) {
  167.                         error("Branch out of Range");
  168.                         dist = Old_pc - (Pc + 1);
  169.                 }
  170.                 emit(lobyte(dist));
  171.                 return;
  172.         default:
  173.                 fatal("Error in Mnemonic table");
  174.         }
  175. }
  176.  
  177. /*
  178.  * bitop --- adjust opcode on bit manipulation instructions
  179.  */
  180. int
  181. bitop(int op, int mode, int class)
  182. {
  183.         if (mode == INDX || mode == INDY)
  184.                 return (op);
  185.         if (class == SETCLR)
  186.                 return (op - 8);
  187.         else if (class == BTB)
  188.                 return (op - 12);
  189.         else {
  190.                 fatal("bitop");
  191.                 return (-1);
  192.         }                       /* never executed - only to shut compiler up */
  193. }
  194.  
  195. /*
  196.  * do_gen --- process general addressing modes
  197.  */
  198. void
  199. do_gen(int op, int mode, int pnorm, int px, int py)
  200. /* int     op;    base opcode */
  201. /* int     mode;   addressing mode */
  202. /* int     pnorm;  page for normal addressing modes: IMM,DIR,EXT */
  203. /* int     px;     page for INDX addressing */
  204. /* int     py;     page for INDY addressing */
  205. {
  206.         switch (mode) {
  207.                 case LIMMED:
  208.                 Optr++;
  209.                 epage(pnorm);
  210.                 emit(op);
  211.                 eval();
  212.                 eword(Result);
  213.                 break;
  214.         case IMMED:
  215.                 Optr++;
  216.                 epage(pnorm);
  217.                 emit(op);
  218.                 eval();
  219.                 emit(lobyte(Result));
  220.                 break;
  221.         case INDY:
  222.                 if (yflag)
  223.                         Cycles += 2;
  224.                 else
  225.                         Cycles += 3;
  226.                 epage(py);
  227.                 do_indexed(op + 0x20);
  228.                 break;
  229.         case INDX:
  230.                 Cycles += 2;
  231.                 epage(px);
  232.                 do_indexed(op + 0x20);
  233.                 break;
  234.         case OTHER:
  235.                 eval();
  236.                 epage(pnorm);
  237.                 if (Force_word) {
  238.                         emit(op + 0x30);
  239.                         eword(Result);
  240.                         Cycles += 2;
  241.                         break;
  242.                 }
  243.                 if (Force_byte) {
  244.                         emit(op + 0x10);
  245.                         emit(lobyte(Result));
  246.                         Cycles++;
  247.                         break;
  248.                 }
  249.                 if (Result >= 0 && Result <= 0xFF) {
  250.                         emit(op + 0x10);
  251.                         emit(lobyte(Result));
  252.                         Cycles++;
  253.                         break;
  254.                 } else {
  255.                         emit(op + 0x30);
  256.                         eword(Result);
  257.                         Cycles += 2;
  258.                         break;
  259.                 }
  260.                 break;
  261.         default:
  262.                 error("Unknown Addressing Mode");
  263.         }
  264. }
  265.  
  266. /*
  267.  * do_indexed --- handle all wierd stuff for indexed addressing
  268.  */
  269. void
  270. do_indexed(int op)
  271. {
  272.         char            c;
  273.  
  274.         emit(op);
  275.         eval();
  276.         if (*Optr++ != ',')
  277.                 error("Syntax: ',' expected");
  278.         c = mapdn(*Optr++);
  279.         if (c != 'x' && c != 'y')
  280.                 warn("Indexed Addressing Assumed");
  281.         if (Result < 0 || Result > 255)
  282.                 warn("Value Truncated");
  283.         emit(lobyte(Result));
  284. }
  285.  
  286. /*
  287.  * epage --- emit page prebyte
  288.  */
  289. void
  290. epage(int p)
  291. {
  292.         if (p != PAGE1)         /* PAGE1 means no prebyte */
  293.                 emit(p);
  294. }
  295.